package com.lhcjh.easyexcel.utils;

import com.alibaba.excel.EasyExcel;
import com.lhcjh.easyexcel.enums.ExcelEnum;
import com.lhcjh.easyexcel.exception.ExcelException;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * excel工具类  by  alibaba.easyexcel
 * 参考地址：https://alibaba-easyexcel.github.io/index.html
 * Created by  longHe
 * 2021/8/19 11:15
 */
@Slf4j
public class EasyexcelUtil {

    private static String initSheetName;

    static {
        initSheetName = "Sheet1";
    }


    /**
     * 根据实体对象写入excel
     *
     * @param data  写入excel的数据
     * @param model 实体对象
     * @param fileName  文件路径
     * @param sheetName  sheet名称
     */
    public static void simpleWrite(List<?> data, Class<?> model, String fileName, String sheetName) {
        //sheet名称，为空的情况下采用默认值
        sheetName = sheetName != null ? sheetName : initSheetName;
        //数据校验
        check(data, fileName, model);
        try {
            //开始写入
            // 如果没有指定model实体，则只能读取实体数据，@ExcelProperty不会生效
            EasyExcel.write(fileName).sheet(sheetName).head(model).doWrite(data);
        } catch (Exception e) {
            //写入失败
            log.error("导出excel文件失败，失败原因：{} ", e.toString());
            e.printStackTrace();
        }


    }




    /**
     * 无实体  +  自定义头部  excel写入
     * 适用场景：没有具体实体对象
     * @param data 需写入excel的数据
     * @param headList 动态头部   动态头部会替换实体类中@ExcelProperty定义的头部
     *
     *             head0.add("地区"); head0.add("天心区");
     *             head1.add("地区"); head2.add("芙蓉区");
     *             head2.add("工作地区"); head1.add("岳麓区");
     *
     *             ====>>>>>  headList.add(head0);headList.add(head1);headList.add(head2)
     *
     *              (head)
     *                   地区        工作地区
     *             天心区  芙蓉区     岳麓区
     *              ---------------------------
     *              (data)
     *             友谊路  五一路     麓谷路
     *             韶山路  黄兴路     梅溪路
     *
     * @param fileName 文件绝对路径（包含文件名）
     * @param sheetName sheet名称
     */
    public static void dynamicHeadAndNoModelWrite(List<?> data, List<List<String>> headList, String fileName, String sheetName) {
        //sheet名称，为空的情况下采用默认值
        sheetName = sheetName != null ? sheetName : initSheetName;
        //数据校验
        check(data, fileName, headList);

        try {
            //开始写入
            EasyExcel.write(fileName).head(headList).sheet(sheetName).doWrite(data);
        } catch (Exception e) {
            //写入失败
            log.error("导出excel文件失败，失败原因：{} ", e.toString());
            e.printStackTrace();
        }

    }





    /**
     * 实体校验
     * @param data 写入excel的数据
     * @param fileName 文件路径
     * @param model 实体对象
     */
    private static void check(List<?> data, String fileName, Class<?> model) {
        commonCheck(data, fileName);
        //对数据载体，实体对象进行非空判断
        if (model == null) {
            log.info("=============请设置写入的实体对象！model=null");
            throw new ExcelException(ExcelEnum.NO_MODEL);
        }

    }

    /**
     *  动态头部数据校验
     * @param data 写入excel的数据
     * @param fileName 文件路径
     * @param headList 自定义头部（动态头部）
     */
    private static void check(List<?> data, String fileName, List<List<String>> headList) {
        commonCheck(data, fileName);
        //对动态头部数据进行空值判断
        if(headList == null || headList.isEmpty()) {
            log.info("=============请设置excel动态头部数据！headList={}", headList);
            throw new ExcelException(ExcelEnum.DYNAMIC_HEAD_LIST_NULL);
        }
    }

    /**
     * data、fileName 这两项是必须校验部分
     * @param data 写入excel的数据
     * @param fileName 文件路径
     */
    public static void commonCheck(List<?> data, String fileName) {
        //对写入excel的数据进行空值判断
        if (data == null || data.isEmpty()) {
            log.info("=============写入excel数据不能为空！data={}", data);
            throw new ExcelException(ExcelEnum.WRITE_LIST_NULL);
        }
        //对文件路径进行判断
        if (fileName == null || fileName.isEmpty()) {
            log.info("=============请指定excel导出路径！fileName={}", fileName);
            throw new ExcelException(ExcelEnum.FILE_NOT_FOUND);
        }

    }



}
